package com.hhck.service.impl;

import com.hhck.constants.Constants;
import com.hhck.dto.AssignRoleDto;
import com.hhck.entity.Page;
import com.hhck.entity.Result;
import com.hhck.entity.Role;
import com.hhck.entity.User;
import com.hhck.mapper.*;
import com.hhck.service.UserService;
import com.hhck.utils.DigestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private AuthMapper authMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 根据账号查询用户
     */
    @Override
    public User queryUserByUserCode(String userCode) {
        return userMapper.selectUserByUserCode(userCode);
    }

    /**
     * 分页查询用户信息
     */
    @Override
    public Page queryUserByPage(Page page, User user) {

        // 获取分页后的用户信息
        List<User> userList = userMapper.selectUserByPage(page, user);

        // 获取用户信息总行数
        Integer count = userMapper.selectUserCount(user);
        // 设置总行数
        page.setTotalNum(count);
        // 设置总页数
        page.setPageCount(page.getPageCount());

        // 封装用户信息
        page.setResultList(userList);

        return page;
    }

    /**
     * 添加用户
     */
    @Override
    public Result saveUser(User user) {

        // 根据账号查询用户，判断账号是否存在
        if (userMapper.selectUserByUserCode(user.getUserCode()) != null) {
            return Result.err(Result.CODE_ERR_BUSINESS, "当前账号已存在！");
        }

        // 密码加密
        user.setUserPwd(DigestUtil.hmacSign(user.getUserPwd()));

        if (userMapper.insertUser(user) == 1) {
            return Result.ok("用户添加成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "用户添加失败！");
    }

    /**
     * 根据用户id更改用户状态（启用或禁用）
     */
    @Override
    public Result modifyUserStateByUserId(User user) {

        if (userMapper.updateUserStateByUserId(user) == 1) {
            return Result.ok("状态修改成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "状态修改失败！");
    }

    /**
     * 根据用户id查询用户已分配的角色
     */
    @Override
    public List<Role> queryUserRoleByUserId(Integer userId) {
        return roleMapper.selectUserRoleByUserId(userId);
    }

    /**
     * 给用户分配角色
     *  1、根据要分配的角色名称查询角色id
     *  2、删除用户的所有角色
     *  3、使用查询出的角色id给用户分配角色
     */
    // 开启事务，多条SQL应该同时成功或者同时失败，否则数据不一致
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveUserRoleByUserId(AssignRoleDto assignRoleDto) {

        // 通过角色名查询要分配的角色id
        List<Integer> roleIdList = roleMapper.selectRoleIdListByRoleName(assignRoleDto.getRoleCheckList());
        // 根据用户id删除用户所有的角色
        userRoleMapper.deleteUserRoleByUserId(assignRoleDto.getUserId());
        // 给用户分配角色
        userRoleMapper.insertUserRoleByUserId(assignRoleDto.getUserId(), roleIdList);

        // 给用户分配完角色后，用户的权限菜单树会发生变化，应当清除缓存，保证数据一致
        redisTemplate.delete(Constants.AUTH_TREE_PREFIX + assignRoleDto.getUserId());
    }

    /**
     * 根据用户id删除用户（逻辑删除）
     */
    // 开启事务
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeUserByUserId(Integer userId) {

        // 删除用户（逻辑删除）
        userMapper.deleteUserByUserId(userId);

        // 删除用户角色关系（物理删除）
        userRoleMapper.deleteUserRoleByUserId(userId);
    }

    /**
     * 批量删除用户（逻辑删除）
     */
    // 开启事务
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchRemoveUser(List<Integer> userIdList) {

        // 删除用户（逻辑删除）
        userMapper.batchDeleteUser(userIdList);

        // 删除用户角色关系（物理删除）
        userRoleMapper.batchDeleteUserRoleByUserIdList(userIdList);
    }

    /**
     * 根据用户id修改用户昵称（注意更新修改者和修改时间）
     */
    @Override
    public Result modifyUserNameByUserId(User user) {

        int num = userMapper.updateUserNameByUserId(user);
        if (num == 1) {
            return Result.ok("修改成功！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "修改失败！");
    }

    /**
     * 根据用户id重置密码
     */
    @Override
    public Result modifyUserPwdByUserId(Integer userId) {

        // 初始密码加密
        String userPwd = DigestUtil.hmacSign("123456");

        int num = userMapper.updateUserPwdByUserId(userId, userPwd);
        if (num == 1) {
            return Result.ok("重置成功，新密码为123456！");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "重置失败！");
    }

    /**
     * 根据用户id查询权限id
     */
    @Override
    public List<Integer> queryUserAuthIdListByUserId(Integer userId) {
        return authMapper.selectAuthIdListByUserId(userId);
    }

}

